package com.bestcem.xm.deliver.convert.grpc;

import com.google.protobuf.*;
import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.util.Timestamps;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

@Mapper
public class BaseConvertMapper {

    /*Boolean---Integer*/
    public static int boolToInteger(Boolean source) {
        if (source) {
            return 1;
        }
        return 0;
    }

    public static Boolean integerToBool(Integer source) {
        return source != null && source != 0;
    }

    /*java.lang.String --- com.google.protobuf.StringValue*/
    public static String stringValueToString(StringValue value) {
        return value.getValue();
    }

    public static StringValue javaStringToStringValue(String value) {
        return StringValue.of(value);
    }

    /*java.lang.Integer --- com.google.protobuf.Int32Value*/
    public static Int32Value integerToInt32(Integer value) {
        return Int32Value.of(value);
    }

    public static Integer int32ToInteger(Int32Value value) {
        return value.getValue();
    }

    /*java.lang.Long --- com.google.protobuf.Int64Value*/
    public static Int64Value longToInt64(Long value) {
        return Int64Value.of(value);
    }

    public static Long int64ToLong(Int64Value value) {
        return value.getValue();
    }

    /*java.lang.Float --- com.google.protobuf.FloatValue*/
    public static FloatValue floatToFloatValue(Float value) {
        return FloatValue.of(value);
    }

    public static Float floatValueToFloat(FloatValue value) {
        return value.getValue();
    }

    /*java.util.Date---com.google.protobuf.util.Timestamps*/
    public static Timestamp javaDateToGoogleTimestamp(Date date) {
        if (date == null) {
            return null;
        }
        return Timestamps.fromMillis(date.getTime());
    }

    public static Date googleTimestampToJavaDate(Timestamp timestamp) {
        if (timestamp == null || timestamp.getSeconds() <= 0) {
            return null;
        }
        return new Date(timestamp.getSeconds() * 1000);
    }


    public static Date localDateTimeToDate(LocalDateTime time) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = time.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /*java.util.LocalDateTime---com.google.protobuf.util.Timestamps*/
    public static Timestamp localDateTimetoGoogleTimestamp(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        return Timestamps.fromMillis(localDateTimeToDate(localDateTime).getTime());
    }

    public static LocalDateTime googleTimestampToLocalDateTime(Timestamp timestamp) {
        if (timestamp == null || timestamp.getSeconds() < 0) {
            return null;
        }
        Date date = new Date(timestamp.getSeconds() * 1000);
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    }

    /*java.util.LocalDate---com.google.protobuf.util.Timestamps*/
    public static Timestamp localDatetoGoogleTimestamp(LocalDate localDate) {
        if (localDate == null) {
            return null;
        }
        LocalDateTime localDateTime = localDate.atStartOfDay();
        return BaseConvertMapper.localDateTimetoGoogleTimestamp(localDateTime);
    }

    public static LocalDate googleTimestampToLocalDate(Timestamp timestamp) {
        if (timestamp == null || timestamp.getSeconds() <= 0) {
            return null;
        }
        return BaseConvertMapper.googleTimestampToLocalDateTime(timestamp).toLocalDate();
    }

    /*jsonString---com.google.protobuf.util.Value*/
    public static String valueToJson(Value value) {
        String json = null;
        try {
            json = JsonFormat.printer().includingDefaultValueFields().print(value);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        return json;
    }

    public static Value jsonToValue(String json) {
        Value.Builder builder = Value.newBuilder();
        try {
            JsonFormat.parser().merge(json, builder);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        return builder.build();
    }

    /*jsonString---com.google.protobuf.util.Struct*/
    public static String structToJson(Struct struct) {
        String json = null;
        try {
            json = JsonFormat.printer().includingDefaultValueFields().print(struct);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        return json;
    }

    public static Struct jsonToStruct(String json) {
        Struct.Builder builder = Struct.newBuilder();
        try {
            JsonFormat.parser().merge(json, builder);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        return builder.build();
    }

    //LocalDateTime -> String
    public static String localDateTimeToStr(LocalDateTime time, String format) {
        if (null == time) {
            return "";
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return df.format(time);
    }

    //String -> LocalDateTime
    public static LocalDateTime strToLocalDateTime(String timeStr, String format) {
        if (StringUtils.isEmpty(timeStr)) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(timeStr, df);
    }
}
